home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 366_01 / ue311c1.arc / BIND.C < prev    next >
C/C++ Source or Header  |  1991-10-30  |  23KB  |  1,037 lines

  1. /*    This file is for functions having to do with key bindings,
  2.     descriptions, help commands and startup file.
  3.  
  4.     written 11-feb-86 by Daniel Lawrence
  5.                                 */
  6.  
  7. #include    <stdio.h>
  8. #include    "estruct.h"
  9. #include    "eproto.h"
  10. #include    "edef.h"
  11. #include    "elang.h"
  12. #include    "epath.h"
  13.  
  14. PASCAL NEAR help(f, n)    /* give me some help!!!!
  15.            bring up a fake buffer and read the help file
  16.            into it with view mode            */
  17.  
  18. int f,n;    /* prefix flag and argument */
  19.  
  20. {
  21.     register BUFFER *bp;    /* buffer pointer to help */
  22.     char *fname;        /* file name of help file */
  23.  
  24.     /* first check if we are already here */
  25.     bp = bfind("emacs.hlp", FALSE, BFINVS);
  26.  
  27.     if (bp == NULL) {
  28. #if SHARED
  29.         strcpy(tname, pathname[1]);
  30.         fname = flook(tname, FALSE);
  31. #else        
  32.         fname = flook(pathname[1], FALSE);
  33. #endif
  34.         if (fname == NULL) {
  35.             mlwrite(TEXT12);
  36. /*                "[Help file is not online]" */
  37.             return(FALSE);
  38.         }
  39.     }
  40.  
  41.     /* split the current window to make room for the help stuff */
  42.     if (splitwind(FALSE, 1) == FALSE)
  43.             return(FALSE);
  44.  
  45.     if (bp == NULL) {
  46.         /* and read the stuff in */
  47.         if (getfile(fname, FALSE) == FALSE)
  48.             return(FALSE);
  49.     } else
  50.         swbuffer(bp);
  51.  
  52.     /* make this window in VIEW mode, update all mode lines */
  53.     curwp->w_bufp->b_mode |= MDVIEW;
  54.     curwp->w_bufp->b_flag |= BFINVS;
  55.     upmode();
  56.     return(TRUE);
  57. }
  58.  
  59. PASCAL NEAR deskey(f, n)    /* describe the command for a certain key */
  60.  
  61. int f,n;    /* prefix flag and argument */
  62.  
  63. {
  64.     register int c;     /* key to describe */
  65.     register char *ptr;    /* string pointer to scan output strings */
  66.     char outseq[NSTRING];    /* output buffer for command sequence */
  67.  
  68.     /* prompt the user to type us a key to describe */
  69.     mlwrite(TEXT13);
  70. /*        ": describe-key " */
  71.  
  72.     /* get the command sequence to describe
  73.        change it to something we can print as well */
  74.     cmdstr(c = getckey(FALSE), &outseq[0]);
  75.  
  76.     /* and dump it out */
  77.     ostring(outseq);
  78.     ostring(" ");
  79.  
  80.     /* find the right ->function */
  81.     if ((ptr = getfname(getbind(c))) == NULL)
  82.         ptr = "Not Bound";
  83.  
  84.     /* output the command sequence */
  85.     ostring(ptr);
  86.     return(TRUE);
  87. }
  88.  
  89. /* bindtokey:    add a new key to the key binding table        */
  90.  
  91. PASCAL NEAR bindtokey(f, n)
  92.  
  93. int f, n;    /* command arguments [IGNORED] */
  94.  
  95. {
  96.     register unsigned int c;/* command key to bind */
  97.     register int (PASCAL NEAR *kfunc)();/* ptr to the requested function to bind to */
  98.     register KEYTAB *ktp;    /* pointer into the command table */
  99.     register int found;    /* matched command flag */
  100.     char outseq[80];    /* output buffer for keystroke sequence */
  101.  
  102.     /* prompt the user to type in a key to bind */
  103.     /* get the function name to bind it to */
  104.     kfunc = getname(TEXT15);
  105. /*            ": bind-to-key " */
  106.     if (kfunc == NULL) {
  107.         mlwrite(TEXT16);
  108. /*            "[No such function]" */
  109.         return(FALSE);
  110.     }
  111.     if (clexec == FALSE) {
  112.         ostring(" ");
  113.         TTflush();
  114.     }
  115.  
  116.     /* get the command sequence to bind */
  117.     c = getckey((kfunc == meta) || (kfunc == cex) ||
  118.             (kfunc == unarg) || (kfunc == ctrlg));
  119.  
  120.     if (clexec == FALSE) {
  121.  
  122.         /* change it to something we can print as well */
  123.         cmdstr(c, &outseq[0]);
  124.  
  125.         /* and dump it out */
  126.         ostring(outseq);
  127.     }
  128.  
  129.     /* if the function is a unique prefix key */
  130.     if (kfunc == unarg || kfunc == ctrlg || kfunc == quote) {
  131.  
  132.         /* search for an existing binding for the prefix key */
  133.         ktp = &keytab[0];
  134.         while (ktp->k_type != BINDNUL) {
  135.             if (ktp->k_ptr.fp == kfunc)
  136.                 unbindchar(ktp->k_code);
  137.             ++ktp;
  138.         }
  139.  
  140.         /* reset the appropriate global prefix variable */
  141.         if (kfunc == unarg)
  142.             reptc = c;
  143.         if (kfunc == ctrlg)
  144.             abortc = c;
  145.         if (kfunc == quote)
  146.             quotec = c;
  147.     }
  148.  
  149.     /* search the table to see if it exists */
  150.     ktp = &keytab[0];
  151.     found = FALSE;
  152.     while (ktp->k_type != BINDNUL) {
  153.         if (ktp->k_code == c) {
  154.             found = TRUE;
  155.             break;
  156.         }
  157.         ++ktp;
  158.     }
  159.  
  160.     if (found) {    /* it exists, just change it then */
  161.         ktp->k_ptr.fp = kfunc;
  162.         ktp->k_type = BINDFNC;
  163.     } else {    /* otherwise we need to add it to the end */
  164.         /* if we run out of binding room, bitch */
  165.         if (ktp >= &keytab[NBINDS]) {
  166.             mlwrite(TEXT17);
  167. /*                "Binding table FULL!" */
  168.             return(FALSE);
  169.         }
  170.  
  171.         ktp->k_code = c;    /* add keycode */
  172.         ktp->k_ptr.fp = kfunc;    /* and the function pointer */
  173.         ktp->k_type = BINDFNC;    /* and the binding type */
  174.         ++ktp;            /* and make sure the next is null */
  175.         ktp->k_code = 0;
  176.         ktp->k_type = BINDNUL;
  177.         ktp->k_ptr.fp = NULL;
  178.     }
  179.  
  180.     /* if we have rebound the meta key, make the
  181.        search terminator follow it            */
  182.     if (kfunc == meta)
  183.         sterm = c;
  184.  
  185.     return(TRUE);
  186. }
  187.  
  188. /* macrotokey:    Bind a key to a macro in the key binding table */
  189.  
  190. PASCAL NEAR macrotokey(f, n)
  191.  
  192. int f, n;    /* command arguments [IGNORED] */
  193.  
  194. {
  195.     register unsigned int c;/* command key to bind */
  196.     register BUFFER *kmacro;/* ptr to buffer of macro to bind to key */
  197.     register KEYTAB *ktp;    /* pointer into the command table */
  198.     register int found;    /* matched command flag */
  199.     register int status;    /* error return */
  200.     char outseq[80];    /* output buffer for keystroke sequence */
  201.     char bufn[NBUFN];    /* buffer to hold macro name */
  202.  
  203.     /* get the buffer name to use */
  204.     if ((status=mlreply(TEXT215, &bufn[1], NBUFN-2)) != TRUE)
  205. /*        ": macro-to-key " */
  206.         return(status);
  207.  
  208.     /* build the responce string for later */
  209.     strcpy(outseq, TEXT215);
  210. /*           ": macro-to-key " */
  211.     strcat(outseq, &bufn[1]);
  212.  
  213.     /* translate it to a buffer pointer */
  214.     bufn[0] = '[';
  215.     strcat(bufn, "]");
  216.     if ((kmacro=bfind(bufn, FALSE, 0)) == NULL) {
  217.         mlwrite(TEXT130);
  218. /*        "Macro not defined"*/
  219.         return(FALSE);
  220.     }
  221.  
  222.     strcat(outseq, " ");
  223.     mlwrite(outseq);
  224.  
  225.     /* get the command sequence to bind */
  226.     c = getckey(FALSE);
  227.  
  228.     /* change it to something we can print as well */
  229.     cmdstr(c, &outseq[0]);
  230.  
  231.     /* and dump it out */
  232.     ostring(outseq);
  233.  
  234.     /* search the table to see if it exists */
  235.     ktp = &keytab[0];
  236.     found = FALSE;
  237.     while (ktp->k_type != BINDNUL) {
  238.         if (ktp->k_code == c) {
  239.             found = TRUE;
  240.             break;
  241.         }
  242.         ++ktp;
  243.     }
  244.  
  245.     if (found) {    /* it exists, just change it then */
  246.         ktp->k_ptr.buf = kmacro;
  247.         ktp->k_type = BINDBUF;
  248.     } else {    /* otherwise we need to add it to the end */
  249.         /* if we run out of binding room, bitch */
  250.         if (ktp >= &keytab[NBINDS]) {
  251.             mlwrite(TEXT17);
  252. /*                "Binding table FULL!" */
  253.             return(FALSE);
  254.         }
  255.  
  256.         ktp->k_code = c;    /* add keycode */
  257.         ktp->k_ptr.buf = kmacro;    /* and the function pointer */
  258.         ktp->k_type = BINDBUF;    /* and the binding type */
  259.         ++ktp;            /* and make sure the next is null */
  260.         ktp->k_code = 0;
  261.         ktp->k_type = BINDNUL;
  262.         ktp->k_ptr.fp = NULL;
  263.     }
  264.  
  265.     return(TRUE);
  266. }
  267.  
  268. /* unbindkey:    delete a key from the key binding table */
  269.  
  270. PASCAL NEAR unbindkey(f, n)
  271.  
  272. int f, n;    /* command arguments [IGNORED] */
  273.  
  274. {
  275.     register int c;     /* command key to unbind */
  276.     char outseq[80];    /* output buffer for keystroke sequence */
  277.  
  278.     /* prompt the user to type in a key to unbind */
  279.     mlwrite(TEXT18);
  280. /*        ": unbind-key " */
  281.  
  282.     /* get the command sequence to unbind */
  283.     c = getckey(FALSE);        /* get a command sequence */
  284.  
  285.     /* change it to something we can print as well */
  286.     cmdstr(c, &outseq[0]);
  287.  
  288.     /* and dump it out */
  289.     ostring(outseq);
  290.  
  291.     /* if it isn't bound, bitch */
  292.     if (unbindchar(c) == FALSE) {
  293.         mlwrite(TEXT19);
  294. /*            "[Key not bound]" */
  295.         return(FALSE);
  296.     }
  297.     return(TRUE);
  298. }
  299.  
  300. PASCAL NEAR unbindchar(c)
  301.  
  302. int c;        /* command key to unbind */
  303.  
  304. {
  305.     register KEYTAB *ktp;    /* pointer into the command table */
  306.     register KEYTAB *sktp;    /* saved pointer into the command table */
  307.     register int found;    /* matched command flag */
  308.  
  309.     /* search the table to see if the key exists */
  310.     ktp = &keytab[0];
  311.     found = FALSE;
  312.     while (ktp->k_type != BINDNUL) {
  313.         if (ktp->k_code == c) {
  314.             found = TRUE;
  315.             break;
  316.         }
  317.         ++ktp;
  318.     }
  319.  
  320.     /* if it isn't bound, bitch */
  321.     if (!found)
  322.         return(FALSE);
  323.  
  324.     /* save the pointer and scan to the end of the table */
  325.     sktp = ktp;
  326.     while (ktp->k_type != BINDNUL)
  327.         ++ktp;
  328.     --ktp;        /* backup to the last legit entry */
  329.  
  330.     /* copy the last entry to the current one */
  331.     sktp->k_code = ktp->k_code;
  332.     sktp->k_type = ktp->k_type;
  333.     sktp->k_ptr.fp     = ktp->k_ptr.fp;
  334.  
  335.     /* null